Guava এবং Java 8 Streams দুটিই Java ডেভেলপমেন্টের জন্য গুরুত্বপূর্ণ টুলস। এদের মধ্যে অনেক মিল থাকলেও, প্রতিটি নির্দিষ্ট পরিস্থিতিতে ভিন্ন ভিন্ন সুবিধা দেয়। এখানে তাদের তুলনা এবং ব্যবহার দেখানো হলো।
গুয়াভা (Guava)
Guava হলো Google-এর দ্বারা তৈরি একটি ওপেন সোর্স লাইব্রেরি যা Java-র বিভিন্ন সীমাবদ্ধতাগুলো কাটিয়ে উন্নত কার্যক্ষমতা প্রদান করে।
গুয়াভা-র বৈশিষ্ট্য:
- Collections Framework Enhancements:
- Immutable Collections
- Multimap, Multiset, Table
- Functional Programming Support:
Function,Predicate,Optional(Java 8-এর আগে)
- Utilities:
- Strings manipulation
- Caching
- I/O Utilities
- Concurrency:
ListenableFutureএবং Futures এর উন্নত ব্যবস্থাপনা
Guava-এর উদাহরণ:
import com.google.common.collect.ImmutableList;
public class GuavaExample {
public static void main(String[] args) {
// Immutable List তৈরি
ImmutableList<String> immutableList = ImmutableList.of("Apple", "Banana", "Guava");
System.out.println("Immutable List: " + immutableList);
}
}
Java 8 Streams
Java 8-এ Streams API প্রবর্তন করা হয়েছে, যা একটি ডেটা প্রসেসিং লাইব্রেরি। এটি functional programming-এর ধারণা ব্যবহার করে ডেটা পরিচালনার একটি সুবিধাজনক উপায় প্রদান করে।
Java 8 Streams-এর বৈশিষ্ট্য:
- Declarative Approach: Imperative কোডের পরিবর্তে ক্লিন এবং ডিক্লারেটিভ কোড।
- Parallel Processing: সহজে মাল্টি-থ্রেডিং ও প্যারালাল প্রসেসিং।
- Lazy Evaluation: শুধুমাত্র প্রয়োজন অনুযায়ী অপারেশন কার্যকর করা হয়।
- Functional Interfaces:
map,filter,reduceইত্যাদি অপারেশন।
Streams-এর উদাহরণ:
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("Apple", "Banana", "Guava", "Mango");
// Guava ফিল্টার করে প্রিন্ট
fruits.stream()
.filter(fruit -> fruit.startsWith("G"))
.forEach(System.out::println); // Output: Guava
}
}
Guava এবং Java 8 Streams-এর তুলনা
| ফিচার | Guava | Java 8 Streams |
|---|---|---|
| Functional Programming Support | Java 8-এর আগে Function, Predicate সরবরাহ করত | Functional interfaces ব্যবহার করে |
| Parallel Processing | সমর্থন নেই | সহজে প্যারালাল প্রসেসিং পরিচালনা করা যায় |
| Immutable Collections | Immutable Collections তৈরি সহজ | Collections immutable করার জন্য আলাদা স্ট্রিম নেই |
| Utility Functions | String manipulation, caching ইত্যাদি সমর্থন করে | শুধুমাত্র ডেটা প্রসেসিং-এ সীমাবদ্ধ |
একত্রে Guava এবং Java 8 Streams ব্যবহার
Guava-এর Immutable Collection এবং Java 8 Streams-এর কম্বিনেশন
import com.google.common.collect.ImmutableList;
import java.util.stream.Collectors;
public class CombinedExample {
public static void main(String[] args) {
// Guava Immutable List
ImmutableList<String> fruits = ImmutableList.of("Apple", "Banana", "Guava", "Mango");
// Java 8 Streams-এর মাধ্যমে ফিল্টার
ImmutableList<String> filteredFruits = fruits.stream()
.filter(fruit -> fruit.contains("a"))
.collect(Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf));
System.out.println("Filtered Fruits: " + filteredFruits);
}
}
- Guava Java 8-এর পূর্ববর্তী সীমাবদ্ধতাগুলো কাটিয়ে উঠতে সাহায্য করে।
- Java 8 Streams functional এবং declarative কোডিং স্টাইল প্রচলিত করে।
এগুলো একসঙ্গে ব্যবহার করে আরও উন্নত, ক্লিন এবং শক্তিশালী কোড তৈরি করা যায়।
Guava Collections এবং Java 8 Streams উভয়ই Java প্রোগ্রামিংয়ে ডেটা প্রসেসিং এবং ম্যানিপুলেশনের জন্য ব্যবহৃত হয়, তবে এগুলোর লক্ষ্য এবং কাজের ধরন আলাদা। এখানে একটি তুলনা দেওয়া হলো:
1. উদ্দেশ্য
| Guava Collections | Java 8 Streams |
|---|---|
| Guava Collections হল ক্লাসিকাল ডেটা স্ট্রাকচারস (যেমন, List, Set, Map) ব্যবহারের ক্ষেত্রে অতিরিক্ত কার্যকারিতা যোগ করতে ব্যবহৃত হয়। | Streams হল ফাংশনাল প্রোগ্রামিং স্টাইল ডেটা প্রক্রিয়া ও ফিল্টার করার জন্য। |
| এটি প্রধানত ডেটা স্ট্রাকচার তৈরিতে, মিউটেবল এবং ইমিউটেবল ডেটা মডেল ম্যানেজ করতে ব্যবহৃত হয়। | এটি ডেটা প্রোসেসিং (যেমন: ফিল্টার, ম্যাপ, রিডিউস) ও পাইপলাইনের জন্য ব্যবহৃত হয়। |
2. প্রধান বৈশিষ্ট্য
Guava Collections:
- Immutable Collections:
- Collections তৈরি করলে তা আর পরিবর্তনযোগ্য থাকে না।
উদাহরণ:
ImmutableList<String> list = ImmutableList.of("A", "B", "C");
- Multimap:
একাধিক মান (values) একই key-তে সংরক্ষণ করতে পারে।
Multimap<String, String> multimap = ArrayListMultimap.create(); multimap.put("Key1", "Value1"); multimap.put("Key1", "Value2");
- BiMap:
Key এবং Value-এর মধ্যে এক-একটি দ্বিমুখী সম্পর্ক তৈরি করে।
BiMap<Integer, String> biMap = HashBiMap.create(); biMap.put(1, "A");
- Table:
দুইটি key দিয়ে ডেটা সংরক্ষণ করতে পারে (row এবং column)।
Table<String, String, Integer> table = HashBasedTable.create(); table.put("Row1", "Column1", 100);
Java 8 Streams:
- Lazy Evaluation:
ডেটা প্রসেসিং শুধুমাত্র প্রয়োজনের সময় হয়।
List<String> filteredList = list.stream() .filter(s -> s.startsWith("A")) .collect(Collectors.toList());
- Pipeline Operations:
একাধিক অপারেশন যেমন
map(),filter(),reduce()একসাথে চেইনে করা যায়।int sum = list.stream() .mapToInt(Integer::valueOf) .sum();
- Parallel Streams:
ডেটা প্রসেসিংকে মাল্টি-থ্রেডেড করতে পারে।
list.parallelStream() .forEach(System.out::println);
3. পারফরম্যান্স
| Guava Collections | Java 8 Streams |
|---|---|
| Collections-এ কাজ করার জন্য আগাম ডেটা প্রস্তুত থাকে। | Streams ডেটা প্রোসেসিং lazy evaluated, তাই পারফরম্যান্সের জন্য কার্যকর। |
| ইমিউটেবল এবং জেনেরিক অপ্টিমাইজড API দেয়। | প্যারালাল প্রসেসিং এবং পাইপলাইন প্রসেসিং দ্রুত ডেটা হ্যান্ডল করতে সাহায্য করে। |
4. কোড স্টাইল
| Guava Collections | Java 8 Streams |
|---|---|
| প্রচলিত ইম্পেরেটিভ স্টাইলের সাথে বেশি মানানসই। | ফাংশনাল স্টাইল প্রোগ্রামিং সহজ করে। |
Guava উদাহরণ:
ImmutableList<String> list = ImmutableList.of("A", "B", "C");
Multimap<String, String> map = ArrayListMultimap.create();
map.put("Key1", "Value1");
map.put("Key1", "Value2");
Java Streams উদাহরণ:
List<String> filteredList = list.stream()
.filter(s -> s.startsWith("A"))
.collect(Collectors.toList());
5. কোথায় কোনটি ব্যবহার করবেন?
| Guava Collections | Java 8 Streams |
|---|---|
| যখন ডেটা স্ট্রাকচার ম্যানেজমেন্ট গুরুত্বপূর্ণ। | যখন ডেটা প্রোসেসিং ও ট্রান্সফর্মেশন গুরুত্বপূর্ণ। |
| Immutable collections বা Multimap ব্যবহার করতে হলে। | ফিল্টারিং, ম্যাপিং, বা প্যারালাল প্রসেসিং প্রয়োজন হলে। |
- Guava Collections হল ডেটা স্ট্রাকচার তৈরিতে শক্তিশালী টুল।
- Java 8 Streams ডেটা প্রসেসিংয়ের জন্য অধিক কার্যকর, বিশেষ করে যখন ফাংশনাল প্রোগ্রামিং প্রয়োজন।
দুটি টুলই বিভিন্ন প্রসঙ্গে অত্যন্ত উপযোগী, এবং বেশিরভাগ সময় একসাথে ব্যবহার করলে সর্বোত্তম ফলাফল পাওয়া যায়।
Guava Function এবং Java Lambda Expression একত্রে ব্যবহার করা হলে কোড আরও সংক্ষিপ্ত এবং কার্যকর হয়। Guava লাইব্রেরি জাভা ৮-এর আগে ফাংশনাল প্রোগ্রামিং স্টাইলের সমর্থন দেওয়ার জন্য Function ইন্টারফেস সরবরাহ করত। কিন্তু জাভা ৮-এর পরে, Lambda Expressions এবং java.util.function প্যাকেজ যুক্ত হয়, যা Guava-এর Function-এর বিকল্প হিসেবে কাজ করে।
Guava Function এবং Lambda Expression-এর সমন্বয়
নীচে Guava Function এবং Java Lambda Expression একত্রে ব্যবহার করার উদাহরণ দেওয়া হলো:
উদাহরণ ১: Guava Function-এর বেসিক ব্যবহার
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import java.util.List;
public class GuavaFunctionExample {
public static void main(String[] args) {
// Guava Function ডিফাইন করা
Function<String, Integer> stringLengthFunction = new Function<String, Integer>() {
@Override
public Integer apply(String input) {
return input.length();
}
};
// একটি String লিস্টের প্রতিটি আইটেমের দৈর্ঘ্য বের করা
List<String> names = List.of("Alice", "Bob", "Charlie");
List<Integer> nameLengths = Lists.transform(names, stringLengthFunction);
System.out.println("Name lengths using Guava Function: " + nameLengths);
}
}
উদাহরণ ২: Lambda Expression ব্যবহার করে Guava Function সরলীকরণ
import com.google.common.collect.Lists;
import java.util.List;
public class GuavaWithLambdaExample {
public static void main(String[] args) {
// Lambda Expression ব্যবহার করে Function ডিফাইন করা
java.util.function.Function<String, Integer> stringLengthFunction = input -> input.length();
// একটি String লিস্টের প্রতিটি আইটেমের দৈর্ঘ্য বের করা
List<String> names = List.of("Alice", "Bob", "Charlie");
List<Integer> nameLengths = Lists.transform(names, stringLengthFunction::apply); // Lambda Function ব্যবহার
System.out.println("Name lengths using Lambda: " + nameLengths);
}
}
উদাহরণ ৩: Guava Function ও Lambda Expression-এর কম্বিনেশন
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import java.util.List;
public class CombinedExample {
public static void main(String[] args) {
// Guava Function এবং Lambda Expression একত্রে ব্যবহার
Function<String, Integer> guavaFunction = input -> input.length(); // Lambda দিয়ে Guava Function
List<String> names = List.of("Alice", "Bob", "Charlie");
List<Integer> nameLengths = Lists.transform(names, guavaFunction::apply);
System.out.println("Name lengths using Guava and Lambda: " + nameLengths);
}
}
কাজের ধাপ:
- Guava Function ব্যবহার:
- Guava-এর
Functionইন্টারফেস একটি ইনপুট নেয় এবং একটি আউটপুট প্রদান করে। - এটিকে
Lists.transform()এর মতো মেথডে ব্যবহার করা যায়।
- Guava-এর
- Lambda Expression ব্যবহার:
- জাভা ৮-এর Lambda Expression সহজেই Guava-এর
Functionএর সমান কাজ করতে পারে।
- জাভা ৮-এর Lambda Expression সহজেই Guava-এর
- Lambda এবং Guava একত্রে:
- Lambda Expression এর মাধ্যমে Guava
Functionকে আরও সংক্ষিপ্ত করা সম্ভব।
- Lambda Expression এর মাধ্যমে Guava
প্রধান সুবিধা:
- Lambda ব্যবহার করে কোডের সরলীকরণ।
- Guava এর বিদ্যমান টুল এবং মেথডগুলোর শক্তি ব্যবহার।
- পুরনো কোডের সাথে সামঞ্জস্য রেখে নতুন ফিচার যুক্ত করা।
লক্ষ্য:
যদি আপনি নতুন কোড লিখছেন, জাভা ৮ বা তার পরবর্তী ফিচার (যেমন java.util.function.Function) সরাসরি ব্যবহার করুন। তবে Guava-এর বিদ্যমান লাইব্রেরির সুবিধা নিতে চাইলে Lambda Expressions ও Guava Function একত্রে ব্যবহার করা যেতে পারে।
Guava লাইব্রেরি Java-তে কাজের সুবিধার্থে প্রচুর utility প্রদান করে। Streams এবং Iterables উভয়ই ডেটা প্রসেসিং এবং পুনরাবৃত্তির (iteration) জন্য ব্যবহৃত হয়, তবে তাদের উদ্দেশ্য, আচরণ এবং ব্যবহারের ক্ষেত্রে পার্থক্য রয়েছে।
Streams
Java 8 থেকে Streams API পরিচিতি পায়। এটি ডেটা প্রসেসিং-এর একটি নতুন পদ্ধতি প্রদান করে, যা কার্যকরী প্রোগ্রামিং ধারণা এবং প্যারালাল প্রসেসিং সহজ করে।
Streams-এর বৈশিষ্ট্য:
- ফাংশনাল প্রোগ্রামিং: Streams ফাংশনাল পদ্ধতিতে কাজ করে।
- লেজি প্রসেসিং (Lazy Evaluation): Streams তখনই ডেটা প্রসেস করে যখন তার প্রয়োজন হয়।
- ডেটা প্রসেসিং পাইপলাইন:
- Streams ডেটাকে একটি পাইপলাইনের মতো প্রক্রিয়াজাত করে।
- Intermediate operations (e.g.,
map,filter) এবং terminal operations (e.g.,collect,forEach) থাকে।
- Parallel Processing সাপোর্ট: Streams সহজে প্যারালাল প্রসেসিং পরিচালনা করতে পারে।
উদাহরণ:
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
Stream.of("apple", "banana", "cherry")
.filter(fruit -> fruit.startsWith("b"))
.map(String::toUpperCase)
.forEach(System.out::println); // Output: BANANA
}
}
Iterables
Iterable হল Java-এর একটি মূল কাঠামো যা java.lang.Iterable ইন্টারফেসের মাধ্যমে প্রদত্ত হয়। এটি Collections Framework-এর ভিত্তি এবং পুনরাবৃত্তি করার জন্য ব্যবহৃত হয়।
Iterables-এর বৈশিষ্ট্য:
- অপরিহার্য ভাবে সিকুয়েন্সিয়াল (Sequential): Iterable সবসময় সিকুয়েন্সিয়ালভাবে কাজ করে।
- ডেটা পুনরাবৃত্তি (Iteration): এটি
for-eachলুপ বাIteratorব্যবহার করে কাজ করে। - সরাসরি ডেটা প্রসেসিং নয়: Iterable শুধুমাত্র পুনরাবৃত্তি করার জন্য ব্যবহৃত হয়, Streams-এর মতো ডেটা প্রসেসিং ক্ষমতা নেই।
- Guava থেকে অতিরিক্ত সুবিধা: Guava-এর
Iterablesক্লাস অতিরিক্ত অপারেশন প্রদান করে, যেমনconcat,filter,transform, ইত্যাদি।
উদাহরণ:
import java.util.Arrays;
public class IterableExample {
public static void main(String[] args) {
Iterable<String> fruits = Arrays.asList("apple", "banana", "cherry");
for (String fruit : fruits) {
System.out.println(fruit);
}
}
}
Guava-এ Streams এবং Iterables-এর সংযোগ:
Guava Streams এবং Iterables-এর মধ্যে কাজ সহজ করতে বিভিন্ন ইউটিলিটি প্রদান করে।
Iterables থেকে Streams-এ রূপান্তর:
Guava Streams API ব্যবহার করে Iterable কে Streams-এ রূপান্তর করা যায়।
উদাহরণ:
import com.google.common.collect.Streams;
import java.util.Arrays;
import java.util.stream.Stream;
public class IterableToStream {
public static void main(String[] args) {
Iterable<String> fruits = Arrays.asList("apple", "banana", "cherry");
Stream<String> fruitStream = Streams.stream(fruits);
fruitStream.map(String::toUpperCase)
.forEach(System.out::println); // Output: APPLE BANANA CHERRY
}
}
Streams থেকে Iterables-এ রূপান্তর:
Streams কে Guava-এর সাহায্যে Iterable এ রূপান্তর করা যায়।
উদাহরণ:
import com.google.common.collect.Iterables;
import java.util.stream.Stream;
public class StreamToIterable {
public static void main(String[] args) {
Stream<String> fruitStream = Stream.of("apple", "banana", "cherry");
Iterable<String> fruits = fruitStream::iterator; // Convert Stream to Iterable
fruits.forEach(System.out::println); // Output: apple banana cherry
}
}
Streams এবং Iterables-এর তুলনা
| বৈশিষ্ট্য | Streams | Iterables |
|---|---|---|
| ব্যবহার | ডেটা প্রসেসিং এবং পাইপলাইনিং | ডেটার উপর পুনরাবৃত্তি |
| লেজি প্রসেসিং | হ্যাঁ | না |
| Functional Support | উচ্চ | সীমিত |
| Parallel Processing | হ্যাঁ | না |
| Guava Integration | Streams.stream() | Iterables ইউটিলিটি ক্লাস |
- Streams জটিল ডেটা প্রসেসিং-এর জন্য উপযুক্ত যেখানে Iterables পুনরাবৃত্তির জন্য ব্যবহার করা হয়।
- Guava লাইব্রেরি Streams এবং Iterables-এর মধ্যে রূপান্তর এবং কাজ সহজ করতে শক্তিশালী সমাধান প্রদান করে।
- Streams যখন ফাংশনাল স্টাইল প্রসেসিং-এর জন্য ব্যবহার হয়, Iterables ডেটার বেসিক traversal-এর জন্য আদর্শ।
গুয়াভা (Guava) একটি জনপ্রিয় Java লাইব্রেরি যা অনেক utility এবং API সরবরাহ করে, যেমন collections, caching, string manipulation, concurrency utilities ইত্যাদি। Guava-কে Java 8 এর সাথে integrate করে আরো আধুনিক এবং কার্যকর কোড লেখা যায়। এখানে Guava এবং Java 8-এর একসাথে ব্যবহারের কিছু গুরুত্বপূর্ণ উদাহরণ দেওয়া হলো:
১. Optional এর ব্যবহার
Java 8-এর java.util.Optional এবং Guava-এর com.google.common.base.Optional প্রায় একই উদ্দেশ্যে ব্যবহৃত হয়। তবে Guava-এর Optional আরও কিছু utility method প্রদান করে।
উদাহরণ:
import com.google.common.base.Optional;
public class GuavaOptionalExample {
public static void main(String[] args) {
Optional<String> guavaOptional = Optional.of("Hello, Guava!");
if (guavaOptional.isPresent()) {
System.out.println("Value is present: " + guavaOptional.get());
} else {
System.out.println("No value present.");
}
// Convert Guava Optional to Java 8 Optional
java.util.Optional<String> javaOptional = guavaOptional.toJavaUtil();
javaOptional.ifPresent(System.out::println);
}
}
Java 8 Integration: Guava-এর Optional সহজেই Java 8-এর Optional-এ রূপান্তর করা যায়।
২. Functional Programming (Predicates এবং Functions)
Guava-এর Predicate এবং Function interface-গুলো Java 8-এর java.util.function package-এর সমান। Guava-এর পুরোনো API-কে Java 8 Lambda expressions দিয়ে সহজেই integrate করা যায়।
উদাহরণ:
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import java.util.Arrays;
import java.util.Collection;
public class GuavaPredicateExample {
public static void main(String[] args) {
Collection<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
// Using Guava Predicate
Predicate<Integer> isEven = input -> input % 2 == 0;
Collection<Integer> evenNumbers = Collections2.filter(numbers, isEven);
System.out.println("Even Numbers: " + evenNumbers);
// Using Java 8 Stream for the same task
numbers.stream()
.filter(num -> num % 2 == 0)
.forEach(System.out::println);
}
}
Java 8 Integration: Java 8-এর Stream API Guava-এর Collections2-এর কাজ সহজতর করে দেয়।
৩. Immutable Collections
Guava-এর ImmutableList, ImmutableSet, এবং ImmutableMap অনেক বেশি নিরাপদ, বিশেষত যখন collections পরিবর্তন করা অনুচিত।
উদাহরণ:
import com.google.common.collect.ImmutableList;
public class GuavaImmutableExample {
public static void main(String[] args) {
// Using Guava ImmutableList
ImmutableList<String> immutableList = ImmutableList.of("A", "B", "C");
System.out.println("Guava ImmutableList: " + immutableList);
// Java 8 Immutable List
java.util.List<String> javaImmutableList = java.util.List.of("A", "B", "C");
System.out.println("Java 8 Immutable List: " + javaImmutableList);
}
}
Java 8 Integration: Guava-এর immutable collections সরাসরি Java 8-এর immutable collections-এর সাথে প্রতিস্থাপনযোগ্য।
৪. Caching (Guava Cache vs Java 8 Map.computeIfAbsent)
Guava-এর Cache API এবং Java 8-এর Map.computeIfAbsent অনেক ক্ষেত্রেই কার্যকর।
উদাহরণ:
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
public class GuavaCacheExample {
public static void main(String[] args) throws InterruptedException {
// Using Guava Cache
Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(5, TimeUnit.SECONDS)
.build();
cache.put("key", "value");
System.out.println("Cached value: " + cache.getIfPresent("key"));
Thread.sleep(6000);
System.out.println("Cached value after expiration: " + cache.getIfPresent("key"));
// Using Java 8 Map.computeIfAbsent
java.util.Map<String, String> map = new java.util.HashMap<>();
String value = map.computeIfAbsent("key", k -> "computedValue");
System.out.println("Value from Java 8 Map: " + value);
}
}
Java 8 Integration: Guava Cache আরো শক্তিশালী এবং কাস্টমাইজেবল হলেও Java 8-এর computeIfAbsent ছোটখাট কাজের জন্য উপযুক্ত।
৫. Strings Manipulation (Joiner এবং Splitter)
Guava-এর Joiner এবং Splitter Java 8-এর String APIs-এর সাথে মিলে যায়।
উদাহরণ:
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
public class GuavaStringExample {
public static void main(String[] args) {
// Using Guava Joiner
String joined = Joiner.on(", ").skipNulls().join("Apple", null, "Banana", "Cherry");
System.out.println("Joined String: " + joined);
// Using Java 8 String.join
String joinedJava8 = String.join(", ", "Apple", "Banana", "Cherry");
System.out.println("Joined String (Java 8): " + joinedJava8);
// Using Guava Splitter
Iterable<String> parts = Splitter.on(",").trimResults().omitEmptyStrings().split(" A, B, ,C ");
parts.forEach(System.out::println);
}
}
Java 8 Integration: Java 8-এর String.join এবং String.split Guava-এর কাজের বিকল্প হিসেবে ব্যবহৃত হতে পারে।
Guava-এর অনেক ফিচার Java 8-এর নতুন API-তে অন্তর্ভুক্ত হয়েছে, তবে Guava-এর ফিচারগুলো এখনও অনেক ক্ষেত্রেই শক্তিশালী এবং কাস্টমাইজেবল। বাস্তব অ্যাপ্লিকেশনগুলোতে Guava এবং Java 8-এর API একসাথে ব্যবহার করলে কোড আরো কার্যকর এবং রিডেবল হয়।
Read more